package org.xi.sims.service.impl;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.collection.ListUtil;
import lombok.AllArgsConstructor;
import org.springframework.data.domain.Example;
import org.springframework.data.domain.ExampleMatcher;
import org.springframework.stereotype.Service;
import org.xi.sims.base.service.impl.IBaseServiceImpl;
import org.xi.sims.config.exception.CloudException;
import org.xi.sims.pojo.entity.Course;
import org.xi.sims.pojo.form.CourseForm;
import org.xi.sims.pojo.form.SearchCourseForm;
import org.xi.sims.pojo.vo.CourseVO;
import org.xi.sims.pojo.vo.SelectVO;
import org.xi.sims.pojo.vo.TimetableVO;
import org.xi.sims.repository.CourseRepository;
import org.xi.sims.service.CourseService;
import org.xi.sims.service.TimetableService;
import org.xi.sims.util.XinUtil;

import java.util.ArrayList;
import java.util.List;
import java.util.Objects;
import java.util.Optional;

/**
 * @author ：xi
 * @time ：Created in 19:10
 * @description：
 */
@Service
@AllArgsConstructor
public class CourseServiceImpl extends IBaseServiceImpl<Course, CourseRepository> implements CourseService {
    private final TimetableService timetableService;


    @Override
    public List<SelectVO> select() {
        return new ArrayList<SelectVO>() {{
            repository.findAll().forEach( one -> {
                this.add(SelectVO.builder().label(one.getName()).value(one.getId()).build());
            });
        }};
    }

    @Override
    public void deleteCourse(Integer id) {
        List<TimetableVO> timetables = timetableService.findVosByCourseId(id);
        if (XinUtil.noNull(timetables)) {
            throw new CloudException("该课程已有已有排课安排，请勿删除!");
        }
        repository.deleteById(id);
    }

    @Override
    public CourseVO saveOrUpdate(CourseForm form) {
        Course course = repository.findByNumber(form.getNumber());

        if (XinUtil.isNull(form.getId())) {
            if (XinUtil.noNull(course)) {
                throw new CloudException("课程号：" + form.getNumber() + " 已存在!");
            }
            course = BeanUtil.copyProperties(form, Course.class);
            return vo(repository.save(course));
        }
        if (XinUtil.noNull(course)) {
            if (!Objects.equals(course.getId(), form.getId())) {
                throw new CloudException("课程号：" + form.getNumber() + " 已存在!");
            }
            BeanUtil.copyProperties(form, course);
        } else {
            course = BeanUtil.copyProperties(form, Course.class);
        }
        return vo(repository.save(course));
    }

    @Override
    public List<CourseVO> query(SearchCourseForm form) {
        Course course = Course.builder().build();
        BeanUtil.copyProperties(form, course);
        ExampleMatcher matcher = ExampleMatcher.matching()
                .withMatcher("name", ExampleMatcher.GenericPropertyMatchers.contains())
                .withMatcher("learnTime" ,ExampleMatcher.GenericPropertyMatchers.contains())
                .withMatcher("credit" ,ExampleMatcher.GenericPropertyMatchers.contains())
                .withMatcher("number" ,ExampleMatcher.GenericPropertyMatchers.contains());
        Example<Course> example = Example.of(course, matcher);

        return vos(repository.findAll(example));
    }

    @Override
    public List<Course> findByName(String name) {
        try {
            ExampleMatcher matcher = ExampleMatcher.matching()
                    .withMatcher("name", ExampleMatcher.GenericPropertyMatchers.contains());
            Example<Course> example = Example.of(Course.builder().name(name).build(), matcher);
            return repository.findAll(example);
        }catch (Exception e) {
            e.printStackTrace();
            return ListUtil.empty();
        }
    }

    @Override
    public List<CourseVO> findVoByName(String name) {
        try {
            return vos(findByName(name));
        }catch (Exception e) {
            e.printStackTrace();
            return ListUtil.empty();
        }
    }

    @Override
    public List<CourseVO> vos(List<Course> courses) {
        return new ArrayList<CourseVO>() {{
            courses.forEach(course -> {
                this.add(vo(course));
            });
        }};
    }

    @Override
    public CourseVO vo(Course course) {
        try {
            CourseVO vo = BeanUtil.copyProperties(course, CourseVO.class);

            return vo;
        }catch (Exception e) {
            e.printStackTrace();
            return null;
        }
    }

    @Override
    public CourseVO findVoById(Integer id) {
        return vo(findById(id));
    }

    @Override
    public CourseVO findVoByIdAndName(Integer id, String name) {
        ExampleMatcher matcher = ExampleMatcher.matching()
                .withMatcher("name", ExampleMatcher.GenericPropertyMatchers.contains());
        Example<Course> example = Example.of(Course.builder().id(id).name(name).build(), matcher);
        Optional<Course> courseOptional = repository.findOne(example);
        if (!courseOptional.isPresent()) {
            return null;
        }
        return vo(courseOptional.get());
    }

    @Override
    public List<CourseVO> findVosByGradeId(Integer gradeId) {
        List<Integer> courseIds = timetableService.findCourseIdByGradeId(gradeId);
        return vos(repository.findAllById(courseIds));
    }
}
